﻿using System;
using System.Collections.Generic;

namespace Basmus.Conel
{
    public class CollectionBinder : IBinder
    {
        public Binding Bind(Type containerType)
        {
            if (containerType.IsArray)
            {
                var elementType = containerType.GetElementType();
                return CreateArrayGenericBinding(elementType);
            }
            if (containerType.IsGenericType && !containerType.IsGenericTypeDefinition)
            {
                var genericTypeDefinition = containerType.GetGenericTypeDefinition();
                if (genericTypeDefinition == typeof(IEnumerable<>))
                {
                    var elementType = containerType.GetGenericArguments()[0];
                    return CreateArrayGenericBinding(elementType);
                }
                if (genericTypeDefinition == typeof(List<>) || genericTypeDefinition == typeof(IList<>))
                {
                    var elementType = containerType.GetGenericArguments()[0];
                    return CreateListGenericBinding(elementType);
                }
            }
            return null;
        }

        public Binding Bind(Type containerType, Type elementType)
        {
            if (containerType.IsArray && elementType == containerType.GetElementType())
            {
                return CreateArrayGenericBinding(elementType);
            }
            if (containerType.IsGenericType && !containerType.IsGenericTypeDefinition)
            {
                var genericTypeDefinition = containerType.GetGenericTypeDefinition();
                if (genericTypeDefinition == typeof (IEnumerable<>))
                {
                    if (elementType == containerType.GetGenericArguments()[0])
                    {
                        return CreateArrayGenericBinding(elementType);
                    }
                }
                if (genericTypeDefinition == typeof(List<>) || genericTypeDefinition == typeof(IList<>))
                {
                    if (elementType == containerType.GetGenericArguments()[0])
                    {
                        return CreateListGenericBinding(elementType);
                    }
                }
            }
            return null;
        }
        private static Binding CreateArrayGenericBinding(Type elementType)
        {
            var bindingType = typeof(ArrayBinding<>).MakeGenericType(elementType);
            var binding = (Binding)Activator.CreateInstance(bindingType);
            return binding;
        }
        private static Binding CreateListGenericBinding(Type elementType)
        {
            var bindingType = typeof(ListBinding<>).MakeGenericType(elementType);
            var binding = (Binding)Activator.CreateInstance(bindingType);
            return binding;
        }
    }
}
